"""
-- coding: utf-8 --
@Time : 2023/8/1
@Author : 张书译
@Describe: UI自动化方法封装
"""

from selenium import webdriver
from selenium.webdriver.support.select import Select
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from Logger import logger


class SeleniumMethod:

    def __init__(self, url, num=0, driverPath=None):
        """
        :param url: 打开网页地址
        :param num: 配置是否显示浏览器：显示：1 无：0
        :param driverPath: 指定本机中chromedriver.exe的位置
        """
        chrome_options = Options()
        service = Service(executable_path=driverPath)
        if num != 0:
            chrome_options.add_argument('--no-sandbox')  # 解决DevToolsActivePort文件不存在的报错
            chrome_options.add_argument('window-size=1920x3000')  # 指定浏览器分辨率
            chrome_options.add_argument('--disable-gpu')  # 谷歌文档提到需要加上这个属性来规避bug
            chrome_options.add_argument('--hide-scrollbars')  # 隐藏滚动条, 应对一些特殊页面
            chrome_options.add_argument('blink-settings=imagesEnabled=false')  # 不加载图片, 提升速度
        if num == 0:
            chrome_options.add_argument('--headless')  # 浏览器不提供可视化页面. linux下如果系统不支持可视化不加这条会启动失败
        if driverPath is not None:
            self.dever = webdriver.Chrome(options=chrome_options, service=service)
        else:
            self.dever = webdriver.Chrome(options=chrome_options)
        self.dever.get(url)

    def Id(self, ID, SEND=None):
        """
        :param SEND: 输入文本
        :param ID: 通过ID获取元素进行操作
        :return:
        """
        try:
            selectTag = self.dever.find_element(By.ID, ID)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{ID}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{ID}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到id：{ID}")

    def Name(self, NAME, SEND=None):
        """
        :param SEND: 输入文本
        :param NAME: 通过NAME获取元素进行操作
        :return:selectTag
        """
        try:
            selectTag = self.dever.find_element(By.NAME, NAME)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{NAME}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{NAME}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到name：{NAME}")

    def CssSelector(self, CssSelector, SEND=None):
        """
        :param SEND: 输入文本
        :param CssSelector: 通过CssSelector获取元素进行操作
        :return:selectTag
        """
        try:
            selectTag = self.dever.find_element(By.CSS_SELECTOR, CssSelector)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{CssSelector}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{CssSelector}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到name：{CssSelector}")

    def PLText(self, PLText, SEND=None):
        """
        :param SEND: 输入文本
        :param PLText: 通过PLText获取元素进行操作
        :return:selectTag
        """
        try:
            selectTag = self.dever.find_element(By.PARTIAL_LINK_TEXT, PLText)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{PLText}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{PLText}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到name：{PLText}")

    def CName(self, CName, SEND=None):
        """
        :param SEND: 输入文本
        :param CName: 通过CLASSNAME获取元素进行操作
        :return:
        """
        try:
            selectTag = self.dever.find_element(By.CLASS_NAME,CName)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{CName}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{CName}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到CLASS_NAME：{CName}")

    def TName(self, TagName, SEND=None):
        """
        :param SEND: 输入文本
        :param TagName: 通过TagName获取元素进行操作
        :return: selectTag
        """
        try:
            selectTag = self.dever.find_element(By.TAG_NAME,TagName)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{TagName}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{TagName}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到TAG_NAME：{TagName}")

    def Text(self, TEXT, SEND=None):
        """
        :param SEND: 输入文本
        :param TEXT: 通过TEXT获取元素进行操作
        :return: selectTag
        """
        try:
            selectTag = self.dever.find_element(TEXT)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{TEXT}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{TEXT}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到TEXT：{TEXT}")

    def xpath(self, XPATH, SEND=None):
        """
        :param SEND: 输入文本
        :param XPATH: 通过XPATH获取元素进行操作
        :return: selectTag
        """
        try:
            selectTag = self.dever.find_element(By.XPATH,XPATH)
            if SEND is None:
                selectTag.click()
                logger.info(f"获取{XPATH}元素，并且点击")
            else:
                selectTag.send_keys(SEND)
                logger.info(f"获取{XPATH}元素，并且输入{SEND}")
            return selectTag
        except EOFError as e:
            logger.info(f"{e}, 未获取到XPATH：{XPATH}")

    def ClickXY(self, X, Y):
        """
        :param X: 坐标轴X
        :param Y: 坐标轴Y
        """
        try:
            ac = ActionChains(self.dever)
            ac.move_by_offset(24,19).click().perform()
            logger.info(f"获取坐标：X：{X}， Y：{Y}元素，并且点击")
        except EOFError as e:
            logger.info(f"{e}, 坐标：X：{X}， Y：{Y}")

    def visible(self, ID, Text):
        """
        定位下拉框数据
        :return:
        """
        selectTag = self.Id(ID)
        select = Select(selectTag)
        select.select_by_visible_text(Text)

    def close(self):
        """关闭浏览器"""
        self.dever.close()

    def quit(self):
        """关闭 Chrome driver进程"""
        self.dever.quit()

    def wait(self, num=5):
        """隐式等待5秒(全局生效：如果超过5秒还未加载完成，就往后执行)"""
        self.dever.implicitly_wait(num)
